home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-09-02 | 10.1 KB | 437 lines | [ TEXT/MMCC]
/******************************************** **** ACL-World **** **** Controls.cp **** **** Created: 26 August 1994 **** Modified: 02 Septembre 1994 **** Version: 0 **** Compatible: C++, Mac System 7 **** **** Description: Collisions demo. **** *******************/ #include "ACL-World.h" //************************************* static const short PICT_PERS = 159; static const short PICT_SIREN = 158; static const short PICT_SONG = 161; static const short PICT_SPACESHIP = 164; static const short PICT_SHIPFIRE = 165; static const short PICT_ENEMY = 166; static const short PICT_ENEMYFIRE = 167; static const short PICT_SPACESHIP2 = 168; static const short PICT_ENEMY2 = 169; static const short PICT_FIELD = 170; static AnimFrameDef anim_pers[] = {{PICT_PERS+1,NULL,0,0,0,afcmd_endsequence}, {PICT_PERS,NULL,0,0,0,afcmd_endanim}}; static AnimFrameDef anim_spaceship[] = {{PICT_SPACESHIP,NULL,0,0,0,afcmd_endsequence}, {PICT_SPACESHIP2,NULL,0,0,0,afcmd_endanim}}; static AnimFrameDef anim_enemy[] = {{PICT_ENEMY,NULL,0,0,0,afcmd_endsequence}, {PICT_ENEMY2,NULL,0,0,0,afcmd_endanim}}; static AnimFrameDef anim_song[] = {{PICT_SONG+0,NULL,10,0,0,afcmd_frame}, {PICT_SONG+1,NULL,10,0,0,afcmd_frame}, {PICT_SONG+2,NULL,90,0,0,afcmd_endanim}}; static AnimFrameDef anim_field[] = {{PICT_FIELD+0,NULL,1,0,0,afcmd_frame}, {PICT_FIELD+1,NULL,1,0,0,afcmd_frame}, {PICT_FIELD+2,NULL,1,0,0,afcmd_endsequence}, {PICT_FIELD+3,NULL,1,0,0,afcmd_frame}, {PICT_FIELD+4,NULL,1,0,0,afcmd_frame}, {PICT_FIELD+5,NULL,1,0,0,afcmd_endanim}}; //************************************* #define TEXTSTEP1 "\pAt any time you can detect if an object collides with another. ACL uses a fast algorithm which allows real time collision detection at the pixel precision." #define TEXTSTEP2 "\pExamine this new example. You can move the spaceship with the arrows of the keyboard and fire with the space bar." #define TEXTSTEP3 "\pIn this situation not all objects should produce collisions. For example the enemy rockets should not collide with spaceship laser and the spaceship should not collide with its laser shooting." #define TEXTSTEP4 "\pACL allows each moveable object to have a collision key. The first part of the key defines the type of the object and the second part indicates which object should produce collision with the specified type." #define TEXTSTEP5 "\pComposed animations produce standard collisions. Each part of the composed anim is considered like a single object and is able to produce collision. In this example the field of the spaceship is a sub-object of the spaceship animation. " //************************************* static AnimGfx *background; static short backwidth,backheight; static Anim *anims[3]; static AnimControl controls[2]; static AnimControl spaceshipcontrols[1], firecontrols[1], enemycontrols[2], enemyfirecontrols[2]; static short anim_h,anim_w; static AnimBase *animbase; //************************************* unsigned short ranged_rdm( unsigned short min, unsigned short max ) { unsigned short qdRdm; unsigned long range, t; qdRdm = Random(); range = max - min; t = (qdRdm * range) / 65536; return( t+min ); } Boolean testanimsong(AnimCObject *a, AnimControl *c) { if (anims[2]->checkcollision(anims[0])) { if (anims[0]->getcurrentsequence()!=1) anims[0]->setsequence(1); } else if (anims[0]->getcurrentsequence()!=0) anims[0]->setsequence(0); return TRUE; } Boolean testrandomsong(AnimCObject *a, AnimControl *c) { controls[1].y = ranged_rdm(anims[0]->gety(),anims[0]->gety()+anim_h); anims[2]->setcurrentframe(0); return TRUE; } Boolean testspaceship(AnimCObject *a, AnimControl *c) { if (c->x<0 && a->getx()+c->x>0) return TRUE; else if (c->x>0 && a->getx()+c->x<backwidth-anim_w) return TRUE; return FALSE; } Boolean testfire(AnimCObject *a, AnimControl *c) { short h; h = ((Anim*)a)->getcurrentframe()->getheight(); if (a->gety() <= -h) a->setdeletenextupdate(TRUE); if (a->checkcollision(anims[1])) { if (anims[1]->getcurrentsequence()!=1) anims[1]->setsequence(1); a->setdeletenextupdate(TRUE); } return TRUE; } Boolean testenemyfire(AnimCObject *a, AnimControl *c) { if (a->checkcollision(anims[0])) { if (anims[0]->getcurrentsequence()!=1) anims[0]->setsequence(1); a->setdeletenextupdate(TRUE); } if (anims[2]) { if (a->checkcollision(anims[2])) { if (anims[2]->getcurrentsequence()!=1) anims[2]->setsequence(1,FALSE); a->setdeletenextupdate(TRUE); } } return TRUE; } Boolean testenemy(AnimCObject *a, AnimControl *c) { Anim *anim; short w,h; w = ((Anim*)a)->getcurrentframe()->getwidth(); h = ((Anim*)a)->getcurrentframe()->getheight(); if (a->getx()>=backwidth) return TRUE; if ( (( ((short)a->getx()) % 10)==0) && ranged_rdm(0,2)) { anim = animbase->createanim(PICT_ENEMYFIRE); anim->setcollisionkey_me(1); anim->setcollisionkey_hit(2); anim->place(a->getx()+(w/2),a->gety()+(h/2) ); w = anims[0]->getcurrentframe()->getwidth(); h = anims[0]->getcurrentframe()->getheight(); enemyfirecontrols[0].cmd = acmd_goto; enemyfirecontrols[0].x = anims[0]->getx()+(w/2); enemyfirecontrols[0].y = anims[0]->gety()+h+10; enemyfirecontrols[0].speed = 6; enemyfirecontrols[0].next = &enemyfirecontrols[1]; enemyfirecontrols[0].testproc = &testenemyfire; enemyfirecontrols[1].cmd = acmd_delete; anim->runcontrol(enemyfirecontrols); anim->setpriority(-1); } return FALSE; } //************************************* Boolean ACLWorld::collisions_advance(void) { short i; Handle ha; Rect rect; static short w,h,h2; step++; GetDItem(dialog,1,&i,&ha,&rect); switch(step) { case 1: SetIText(ha,TEXTSTEP1); anims[0] = animbase->createanim(anim_pers); anims[1] = animbase->createanim(PICT_SIREN); anims[0]->findmaxsize(&w,&h); anim_h = h; anims[0]->place( (backwidth/2)-(40+w), (backheight/2)-(h/2) ); anims[1]->findmaxsize(NULL,&h2); anims[1]->place( (backwidth/2)+40, ((backheight/2)-(h2/2))-(h2-h) ); anims[2] = animbase->createanim(anim_song); anims[2]->setanimflags(ANF_PINGPONG); anims[2]->setcollisionkey_me(1); anims[2]->setcollisionkey_hit(2); anims[0]->setcollisionkey_me(2); anims[0]->setcollisionkey_hit(1); controls[0].cmd = acmd_place; controls[0].x = anims[1]->getx()+7; controls[0].y = anims[1]->gety()+10; controls[0].testproc = &testrandomsong; controls[0].next = &controls[1]; controls[1].cmd = acmd_goto; controls[1].speed = 1; controls[1].x = anims[0]->getx()-(w+10); controls[1].testproc = &testanimsong; controls[1].next = &controls[0]; anims[2]->runcontrol(controls); return FALSE; case 2: SetIText(ha,TEXTSTEP2); animbase->setsortflags(ASORT_PRIORITY); for(i=0;i<3;i++) {delete anims[i]; anims[i]=NULL;} anims[0] = animbase->createanim(anim_spaceship); anims[0]->setcollisionkey_me(2); anims[0]->setcollisionkey_hit(1); anims[0]->findmaxsize(&w,&h); anim_w = w; anims[0]->place( (backwidth/2)-(w/2), backheight-(h+5) ); spaceshipcontrols[0].cmd = acmd_move; spaceshipcontrols[0].x = 0; spaceshipcontrols[0].y = 0; spaceshipcontrols[0].next = &spaceshipcontrols[0]; spaceshipcontrols[0].testproc = &testspaceship; anims[0]->runcontrol(spaceshipcontrols); firecontrols[0].cmd = acmd_move; firecontrols[0].x = 0; firecontrols[0].y = -8; firecontrols[0].next = &firecontrols[0]; firecontrols[0].testproc = &testfire; anims[1] = animbase->createanim(anim_enemy); anims[1]->setcollisionkey_me(4); anims[1]->setcollisionkey_hit(8); anims[1]->findmaxsize(&w,&h); enemycontrols[0].cmd = acmd_move; enemycontrols[0].x = 2; enemycontrols[0].y = 0; enemycontrols[0].next = &enemycontrols[1]; enemycontrols[1].cmd = acmd_place; enemycontrols[1].x = -w; enemycontrols[1].y = 18; enemycontrols[1].testproc = &testenemy; enemycontrols[1].next = &enemycontrols[0]; anims[1]->runcontrol(enemycontrols); return FALSE; case 3: SetIText(ha,TEXTSTEP3); return FALSE; case 4: SetIText(ha,TEXTSTEP4); return FALSE; case 5: SetIText(ha,TEXTSTEP5); anims[2] = anims[0]->createanim(anim_field); anims[2]->setcollisionkey_me(2); anims[2]->setcollisionkey_hit(1); anims[2]->setpriority(10); anims[2]->place(-5,-13); return FALSE; } return TRUE; } //************************************* Boolean ACLWorld::do_collisions(void) { Point p; char key; short res; Boolean done = FALSE; Anim *anim; pleasewait(TRUE); ::animbase = animbase = new AnimBase(); animbase->newgfx(PICT_SIREN); animbase->newgfx(PICT_SHIPFIRE); animbase->newgfx(PICT_ENEMYFIRE); animbase->preload_framedef(anim_pers); animbase->preload_framedef(anim_song); animbase->preload_framedef(anim_spaceship); animbase->preload_framedef(anim_enemy); animbase->preload_framedef(anim_field); backwidth = 460; backheight = 217; animbase->buildbuffer(460,217); animbase->setbasex(17); animbase->setbasey(8); pleasewait(FALSE); step = 0; openbasedialog(); SetWTitle(dialog,"\pCollisions"); collisions_advance(); for(;;) { if (step>1) { anims[0]->setsequence(0); anims[1]->setsequence(0); if (anims[2]) anims[2]->setsequence(0,FALSE); } res = processbasedialog(key,p); if (res==DO_QUIT) {done=TRUE; break;} else if (res==DO_MENU) break; else if (res==DO_CONTINUE && collisions_advance()) break; else if (res==DO_KEY && step>1) { switch(key) { case 28: spaceshipcontrols[0].x = -4; break; case 29: spaceshipcontrols[0].x = 4; break; case ' ': anim = animbase->createanim(PICT_SHIPFIRE); anim->setcollisionkey_me(8); anim->setcollisionkey_hit(4); anim->runcontrol(firecontrols); anim->place(anims[0]->getx()+23,anims[0]->gety()); anim->setpriority(-1); break; } } else if (res==DO_KEYUP && step>1) { switch(key) { case 28: case 29: spaceshipcontrols[0].x = 0; break; } } } closebasedialog(); delete animbase; return done; } //*************************************